package com.fujimana.rockincat.restree.phase;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import com.fujimana.rockincat.restree.exception.UnknowResourceException;
import com.fujimana.rockincat.restree.exception.UnsupportedMethodException;
import com.fujimana.rockincat.restree.init.Init;
import com.fujimana.rockincat.restree.proxy.MethodMetaData;
import com.fujimana.rockincat.restree.proxy.ResourceProxy;
import com.fujimana.rockincat.restree.util.HttpUtils.HttpStatusCode;

public class BuidResourceTreePahse implements Phase {

	@Override
	public void execute(Map<String, Object> context) {
		HttpServletRequest request = (HttpServletRequest) context
				.get(HttpServletRequest.class.getName());
		Init init = (Init) context.get(Init.class.getName());
		
		
		List<String> resTree = splitPath(request.getPathInfo());
		Iterator<String> it = resTree.iterator();
		
		String endpoint = it.next();
		ResourceProxy proxy = init.getEndpoint(endpoint);
		
		Map<String, ResourceProxy> proxyLinkMap = new LinkedHashMap<String, ResourceProxy>();
		
		proxyLinkMap.put(endpoint, proxy);

		if (proxy != null) {
			while (it.hasNext()) {
				String res = it.next();

				proxy = proxy.getResource(res, init.getResource());
				if (proxy == null) {
					break;
				}
				
				proxyLinkMap.put(res, proxy);
			}
		}

		if (proxy == null) {
			throw new UnknowResourceException(HttpStatusCode.NOT_FOUND, "TODO");
		}

		String m = ((HttpServletRequest) request).getMethod().toLowerCase();
		MethodMetaData method = init.getMethodMetaData(m);

		if (method == null
				|| proxy.hasInvokeMethod(method.getAnnotatin()) == false) {
			throw new UnsupportedMethodException(
					HttpStatusCode.METHOD_NOT_ALLOWED, "TODO");
		}

		context.put(ResourceProxy.class.getName(), proxy);
		context.put(MethodMetaData.class.getName(), method);
		
		context.put("resourceTree", proxyLinkMap);
	}

	@Override
	public String getId() {
		return BuidResourceTreePahse.class.getSimpleName();
	}

	private List<String> splitPath(String path) {
		List<String> resTree = new ArrayList<String>();

		Matcher matcher = Pattern.compile("([^/]+)(/|$)").matcher(path);
		while (matcher.find()) {
			resTree.add(matcher.group(1));
		}

		return resTree;
	}
	
	@Override
	public boolean isChain() {
		return true;
	}
}
